package com.cgy.utils.base.map;

import com.cgy.utils.base.list.ListHelper;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cgy.utils.base.constant.Strings.EMPTY;

/**
 * map工具类
 * @author CHTK
 */
public class MapHelper {

    public static final int DEFAULT_SIZE = 1 << 4;
    /**
     * 创建Map<K, V>
     * @return
     */
    public static <K, V>Map<K, V> newMap() {
        return new HashMap<>(DEFAULT_SIZE);
    }
    /**
     * 创建Map<K, V>
     * @return
     */
    public static <V, K> Map<K,V> newMap(Map<K,V> map) {
        if(isEmpty(map)) {
            return newMap();
        }
        return map;
    }

    /**
     * 初始化
     * @param values
     * @return
     */
    public static Map<String, Object> newMap(String... values) {
        if(values.length == 0) {
            return newMap();
        } else {
            Map<String, Object> objectObjectMap = newMap(values.length);
            for (String value : values) {
                String[] split = value.split(",");
                if(split.length > 0) {
                    for (String splice : split) {
                        if(StringUtils.isNotBlank(splice)) {
                            String[] split1 = splice.split(":");
                            if(split1.length == 2) {
                                objectObjectMap.put(split1[0], split1[1]);
                            }
                        }
                    }
                }
            }
            return objectObjectMap;
        }
    }

    /**
     * map是否为空
     * @param map 元数据
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> boolean isEmpty(final Map<K,V> map) {
        return mapSize(map) == 0;
    }

    /**
     * 创建Map<K, V>
     * @return
     */
    public static <K, V>Map<K, V> newMap(final int size) {
        return new HashMap<>(size);
    }

    /**
     * 创建Map<String, Object>
     * @return
     */
    public static Map<String, Object> newMapStringObject() {
        return newMap();
    }
    /**
     * 创建Map<String, String>
     * @return
     */
    public static Map<String, String> newMapStringString() {
        return newMap();
    }

    /**
     * map长度
     * @param map 原数据
     * @param <V>
     * @param <K>
     * @return
     */
    public static <V, K> int mapSize(final Map<K,V> map) {
        return null == map ? 0 : map.size();
    }

    /**
     * 添加值
     * @param t 元数据
     * @param k 索引
     * @param v 值
     * @param <V>
     * @param <K>
     */
    public static <V, K> void put(Map<K,V> t, final K k, final V v) {
        if(isEmpty(t)) {
            t = newMap();
        }
        if(null != k) {
            t.put(k, v);
        }
    }

    /**
     * 遍历
     * @param sources 元数据
     * @param iteratorHandler 遍历方法
     * @return
     */
    public static <K, V> Map<K, V> iterator(final Map<K, V> sources, final IteratorHandler<K, V> iteratorHandler) {
        if(isEmpty(sources)) {
            return newMap();
        }

        for (Map.Entry<K, V> entry : sources.entrySet()) {
            iteratorHandler.next(entry.getKey(), entry.getValue());
        }

        return sources;
    }

    /**
     * 获取所有key
     * @param t
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> List<K> keyList(final Map<K, V> t) {
        if(isEmpty(t)) {
            return ListHelper.newArrayList();
        }
        return ListHelper.toList(t.keySet());
    }
    /**
     * 获取所有 value
     * @param t
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> List<V> valueList(final Map<K, V> t) {
        if(isEmpty(t)) {
            return ListHelper.newArrayList();
        }
        return ListHelper.toList(t.values());
    }

    /**
     * 返回Object类型
     * @param map
     * @param key
     * @return
     */
    public static final Object objects(final Map<String, Object> map, final String key) {
        return null == map ? null : map.get(key);
    }
    /**
     * 返回 String 类型
     * @param map
     * @param key
     * @return
     */
    public static final String strings(final Map<String, Object> map, final String key) {
        return strings(map, key, EMPTY);
    }
    /**
     * 返回 String 类型
     * @param map
     * @param key
     * @param defaultValue
     * @return
     */
    public static final String strings(final Map<String, Object> map, final String key, final String defaultValue) {
        final Object objects = objects(map, key);
        return null ==  objects? defaultValue : objects.toString();
    }
    /**
     * 返回 int 类型
     * @param map
     * @param key
     * @return
     */
    public static final int ints(final Map<String, Object> map, final String key) {
        return ints(map, key);
    }
    /**
     * 返回 int 类型
     * @param map
     * @param key
     * @param defaultValue
     * @return
     */
    public static final int ints(final Map<String, Object> map, final String key, final int defaultValue) {
        String strings = strings(map, key);
        return NumberUtils.toInt(strings, defaultValue);
    }

    /**
     * 返回 long 类型
     * @param map
     * @param key
     * @return
     */
    public static final long longs(final Map<String, Object> map, final String key) {
        return longs(map, key);
    }
    /**
     * 返回 int 类型
     * @param map
     * @param key
     * @param defaultValue
     * @return
     */
    public static final long longs(final Map<String, Object> map, final String key, final int defaultValue) {
        final String strings = strings(map, key);
        return NumberUtils.toLong(strings, defaultValue);
    }
    /**
     * 返回boolean类型
     * @param map
     * @param key
     * @return
     */
    public static final Boolean booleans(final Map<String, Object> map, final String key) {
        final String string = strings(map, key);
        return BooleanUtils.toBoolean(string);
    }



    /**
     * 遍历
     */
    public static interface IteratorHandler<K, V> {
        /**
         * 每个节点
         * @param k 索引
         * @param v 值
         * @return
         */
        public void next(K k, V v);
    }
}
